Свой VPN с поддержкой IPv6 на базе Wireguard

Иногда возникает необходимость получить доступ к сайтам, например, https://refactoring.guru или https://leafletjs.com, но по каким-то причинам эти сайты заблокирован в вашей стране. А может быть вы просто хотите получить доступ к сайтам, которые доступны только по IPv6, а ваш провайдер не предоставляет вам такой возможности. Одним из выходов может стать VPN. Однако покупать VPN где-то на стороне при наличии собственного VPS сервера, где интернет работает нормально, просто лишняя трата денег. В таком случае возникает вопрос: а как, собственно, организовать этот самый VPN? В интернете есть множество инструкций, но они обычно не затрагивают тему протокола IPv6 или затрагивают, но там используются спорные решения.

Одним из популярных вариантов организации VPN является Wireguard. Сам по себе, Wireguard, довольно прост, но при этом его можно использовать в любых схемах: «точка-точка», «звезда» и даже mesh-сеть. В дальнейшем будет использоваться схема «звезда», которая подразумевает использование отдельного сервера и наличие, минимум, одного или нескольких клиентов.

Если с IPv4 всё понятно, поскольку большинство руководств сходятся к решению с использованием серой адресации с организацией NAT на сервере. По сути, это стандартная схема для IPv4 адресации. Адресов IPv4 мало и стоят они дорого, поэтому никто, в здравом уме, не будет использовать «белые» адреса непосредственно на устройствах, если, конечно, это не сервер, который доступен в интернете. А вот с IPv6 не всё так однозначно.

Сам по себе протокол IPv6 строится на том, что никому не потребуется использовать NAT. При этом, это не означает, что сам по себе NAT в IPv6 недоступен. NAT для IPv6 доступен (обычно его называют NAT66), но его использование не рекомендуется, а в некоторых случаях это даже вредно. К тому же всегда есть возможность его не использовать, в противовес IPv4.

Выдавать IPv6 адреса хостинг-провайдеры могут по разному:

  1. Выдача IPv6 адресов поштучно. Самый странный вариант. Если у вашего хостинг-провайдера так, то, скорее всего, стоит просто сменить его на другого, даже к контексте использования VPS для обычного сервера, не говоря уже об использовании как VPN. С некоторой долей вероятности тоже можно получить VPN с IPv6, но далее этот вариант просто не рассматривается. После прочтения материала вы сами сможете понять что вам нужно делать, если вы всё-таки решитесь использовать подобного провайдера.

  2. Выдача сети /64. Наиболее часто встречающийся вариант для мелких провайдеров. Иногда есть возможность через поддержку получить сеть /63 или, даже, ещё большего размера, что будет рассмотрено в следующем варианте. Наличие только /64 не самый хороший вариант для VPN, но с ним уже можно работать.

  3. Вариант не особо отличается от предыдущего, но вместо сети /64 вам выдают сеть большего размера (до /48), т.е. в вашем распоряжении оказывается адресация некоторого количества сетей /64. Например при /48 — 65536 штук.

  4. Маршрутизация определённого префикса IPv6 на вашу виртуальную машину. Самый редкий вариант среди мелких провайдеров, в публичном доступе такое почти не встречается, но, возможно есть возможность получить префикс через техническую поддержку. Этот вариант подразумевает, что ваш хостинг провайдер прописал маршрут на ваш виртуальный сервер для выделенного вам префикса. Вам может быть выдана сеть от /64 до /48, которые без костылей могут быть использованы вами для организации VPN.

Сложность настройки VPN постепенно уменьшается от 1 до 4 варианта, поэтому начнём с 4 варианта и постепенно поднимемся вверх.

Шаг 1: Включение маршрутизации на сервере VPN

Самым простым для настройки является вариант, когда ваш провайдер прописал маршрут для сети или сетей /64 на вашу виртуальную машину. В таком случае единственное, что вам нужно будет сделать, чтобы обеспечить работу VPN — это включить маршрутизацию на вашей машине.

Для IPv4 маршрутизация включается с помощью sysctl путём установки

net.ipv4.ip_forward=1

Для IPv6 это делается аналогично:

net.ipv6.conf.all.forwarding = 1

Но есть одно НО! Если ваша машина получает адреса в автоматическом режиме, то после включения маршрутизации она перестанет принимать анонсы маршрутизаторов, а значит, больше не сможет получить адрес в автоматическом режиме. Чтобы это исправить, включите

net.ipv6.conf.ens3.accept_ra = 2

В данном примере `ens3` — это сетевой интерфейс нашего VPS, откуда мы хотим принимать анонсы маршрутизатора. На большинстве хостингов назначение IPv6 адресов на VPS производилось путём ручной настройки, а значит и принимать RA не требуется, т.е. данную настройку можно пропустить.

Теперь осталось выделить сеть /64 из доступного вам диапазона, назначить один из адресов на интерфейс Wireguard на VPS, а также выдать каждому клиенту по IPv6 адресу из этого же диапазона. Всё прописывается в конфигурации сервера и клиентов. На этом настройка VPN для 4 варианта будет закончена.

Шаг 2: Обеспечиваем маршрутизацию пакетов для сервера без выделенного префикса

Теперь перейдём к варианту, когда нам выделено, в лучшем случае, от /63 до /48, в худшем /64. Сначала рассмотрим лучший вариант.

Первое, что необходимо проверить, что сетевой интерфейс вашего сервера настроен на сеть стандартного размера /64. В этом случае принятый пакет из диапазона, выходящего за его пределы, будет передан в соответствии с таблицей маршрутизации.

В IPv6 есть функция обнаружения соседей. Это означает, что если хост хочет с кем-то связаться, то в первую очередь отправляет запрос на поиск соседа с заданным адресам. Если будет получен ответ, то хост сможет направить данные напрямую, минуя маршрутизатор. Если хост назначения недоступен, то узел воспользуется таблицей маршрутизации и отправит пакет на соответствующий маршрутизатор. Для IPv4 эта ситуация немного необычна. А в IPv6 пакеты между разными диапазонами адресов могут ходить напрямую между хостами, а также, существуют ситуации, когда даже хосты в одной сети будут общаться через маршрутизатор.

Поскольку мы назначили для своего сервера сеть /64, то при попытке маршрутизатора провайдера найти соседа с адресом, который не попадает в данную подсеть, наш хост будет эти запросы игнорировать. Чтобы этого не происходило, можно воспользоваться специальной службой NDP proxy. Этот служба может пересылать запросы на поиск соседей и возвращать ответы и отвечать на указанные запросы положительным ответом. К сожалению, Wireguard работает на более высоком сетевом уровне, поэтому единственным вариантом для нас является просто выдача положительных ответов при запросе адресов, которые используются в VPN.

Одним из вариантов решения задачи — это установка пакета ndppd. Пакет точно доступен в стандартных поставках Ubuntu и Fedora в официальных репозиториях. Установите его с помощью вашего пакетного менеджера. Конфигурация ndppd достаточно простая. Файл конфигурации сервиса расположен по адресу /etc/ndppd.conf. Содержимое этого файла должно быть примерно таким:

proxy ens3 {
rule 2001:0db8:827:fcde:cafb:073d:a65e:25b0 {
static
}
}

Данная конфигурация означает, что если приходит запрос на интерфейс ens3 с запросом соседа по адресу 2001:0db8:827:fcde:cafb:073d:a65e:25b0, то необходимо ответить, что это наш адрес. Записи rule можно повторить несколько раз и, даже, указать в каждой записи не отдельный адрес, а целый диапазон. Однако сам ndppd не приветствует широкую маску сети. Если клиентов VPN немного, лучше для каждого из них создать свою запись.

Шаг 2.1: Что делать, если у нас только сеть /64

Это самый неблагоприятный вариант, но при этом мы всё равно сможем обеспечить работу нашего VPN. Вообще, сама идея разделять диапазон /64 на сети меньшего размера, мягко говоря, не приветствуется. Но поскольку у нас нет другого выхода, то придётся это сделать.

Поскольку мы используем VPS, то вряд ли будем использовать механизм SLAAC, который работает только с сетями /64. К тому же, в большинстве случаев, адресация для VPS прописывается вручную, просто потому, что у сервера должен быть строго определённый адрес. Исходя из этого можно разделить сеть /64 на сети меньшего размера. Как делить? Если вы не планируете запускать на сервере другие сервисы VPN, то одним из вариантов являются сети /65, т.е. сеть /64 мы делим пополам. В этом случае для клиентов VPN нам доступны почти все биты из диапазона /64, кроме старшего. При таком разделении наш адрес будет выглядеть как обычный адрес, который, например, мог бы быть выделен через SLAAC.

Если кроме Wireguard вы хотите, например, также запустить на вашем сервере ещё и OpenVPN, то вам может понадобиться ещё одна сеть для этого сервиса. В таком случае вы можете выбрать сеть /66. Конечно, в этом случае вам нужно учитывать уже не один старший бит, а два. Можно и дальше сужать сети, но при этом адреса ваших клиентов будут уже не так похожи на адреса, которые обычно выделяются при использовании механизма SLAAC. Вариант отличные от /65 вы можете организовать самостоятельно.

Чтобы ваш сервер обеспечил маршрутизацию пакетов, которые необходимо будет отправить клиенту VPN, необходимо урезать сеть в настройках сетевого интерфейса. Вместо /64 указываем выбранную маску, например, /65. После этого настройка вашего VPN сервера не отличается от настроек, которые мы делали на шаге 2. Конечно, маску /65 нужно указать и в настройках Wireguard на вашем сервере.

Практическая часть

Дабы не вдаваться в подробности, будем считать, что вы ознакомились с моей «Шпаргалкой по Wireguard» или любой другой инструкции, которых очень много в интернете, и вам не надо объяснять как генерировать ключи.

Включаем маршрутизацию на VPS путём установки параметров, например, путём добавления файла /etc/sysctl.d/20-vpn.conf и загрузки их через sysctl -p или путём перезагрузки VPS:

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding = 1

Сгенерируйте пару ключей для своего VPN сервера, например так

wg genkey | tee private.key | wg pubkey > public.key

Для дополнительной безопасности для каждого клиента может быть сгенерирован ключ PSK, но это не обязательно:

wg genpsk > psk.key

Аналогичным образом сгенерируйте ключи для всех ваших клиентов. После этого можно сформировать серверную конфигурацию для Wireguard.

[Interface]
Address = 192.168.0.1/24, 2001:0db8:827:fcde::1/64
PrivateKey = <SERVER_PRIVATE_KEY>
ListenPort = <SERVER_PORT>

[Peer]
PublicKey = <CLIENT_PUBLIC_KEY>
AllowedIPs = 192.168.0.2, 2001:0db8:827:fcde::1ce:1ce:babe
PresharedKey = <PRESHARED_KEY>

Не сложно догадаться, что <SERVER_PRIVATE_KEY> — это закрытый ключ сервера, а <CLIENT_PUBLIC_KEY> — это публичный ключ клиента. 192.168.0.0/24 — это сеть IPv4 для нашего подключения, а адрес 192.168.0.1 будет присвоен интерфейсу Wireguard. По аналогии, 2001:0db8:827:fcde::/64, соответственно сеть IPv6, а адрес 2001:0db8:827:fcde::1 — адрес интерфейса Wireguard. Опция PresharedKey не обязательная, но если она указана на сервере, то она также должна быть указана в конфигурации клиента, значение ключей на сервере и клиенте должно совпадать.

Секция [Peer] должна быть создана для каждого клиента. В AllowedIPs должны быть указаны IP адреса и сети, которые мы ожидаем от клиента.

Конфигурации клиентов должны иметь вид

[Interface]
Address = 192.168.0.2, 2001:0db8:827:fcde:beef:1ce:1ce:babe
PrivateKey = <CLIENT_PRIVATE_KEY>

[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
AllowedIPs = 0.0.0.0/0, 2000::/3
Endpoint = <SERVER_NAME>:<SERVER_PORT>
PresharedKey = <PRESHARED_KEY>
PersistentKeepalive = 20

Аналогично, на клиенте: <CLIENT_PRIVATE_KEY> — закрытый ключ клиента, <SERVER_PUBLIC_KEY> — публичный ключ сервера. В Endpoint необходимо указать адрес <SERVER_NAME> и порт <SERVER_PORT> сервера, которые соответствуют указанным параметрам в настройках сервера. Параметр PresharedKey должен присутствовать, если он есть в секции [Peer] для этого клиента, содержимое ключа должно совпадать.

PersistentKeepalive может также отсутствовать. Но если указано, то клиент каждое указанное количество секунд будет отправлять пакет данных. Это полезно в тех случаях, когда клиент находится за NAT или Firewall, которые при отсутствии активности могут запретить удалённому хосту присылать вам ответы.

Чтобы обеспечить доступ клиентов в интернет по протоколу IPv4, необходимо включить NAT, например, с помощью скриптов, которые необходимо добавить в секцию `[Interface]` на сервере, и отключить их, если клиенты отключаются.

PostUp = iptables -A FORWARD -i %i -j ACCEPT -w 10; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE -w 10
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE

Автоматизация

Конечно, делать все необходимые настройки руками, особенно если новый клиент вашего VPN появляется не часто, это просто сущее наказание. Поэтому я задумался об автоматизации. В качестве базы был найден скрипт nebulakl/wireguard-config-generator. Он не совсем подходил под мои нужды, поэтому я его переделал и выложил в fsa/wireguard-config-generator.

Скрипт позволяет генерировать конфигурацию для сервера VPN на базе Wireguard. Далее можно генерировать необходимое количество конфигураций клиентов. Скрипт сохранил возможность использования NAT66, как было в оригинальном скрипте, но включение NAT66 производится явно через редактирование конфигурации сервера. По умолчанию скрипт использует «серую» адресацию, как в оригинальном скрипте.


ссылка на оригинал статьи https://habr.com/ru/articles/752866/

Самый быстрый браузер

В июле 2023 года произошло важное событие — Firefox превзошёл Chrome в популярном тесте Speedometer, который измеряет скорость работы браузеров.

Были времена, когда Firefox считался медленным и неповоротливым браузером, потребляющим много памяти и в целом «тормозным». Когда появился Chrome, то некоторые пользователи перешли на него из-за лучшей производительности. Сейчас ситуация кардинально меняется.

Как Mozilla сумела добиться такого результата?

Оптимизация скорости

Разработчики Firefox долго и упорно работали над оптимизацией и устранением багов — и в конце концов эта работа дала эффект. Была установлена чёткая программа действий с измеримыми результатами.

В первую очередь Mozilla разработала и внедрила фреймворк Raptor для проведения автоматических тестов, чтобы измерять производительность своих продуктов — и интегрировала его в CI, то есть в стандартный процесс разработки и выпуска новых версий ПО. Другими словами, новые версии программ не выпускаются без предварительного бенчмарка. Автоматизацией тестов занимается отдельная группа девопсов PerfTest Team под руководством «шерифа по производительности» Дейва Ханта, опытного специалиста по автоматизации.

Два крупнейших скачка в производительности Firefox в марте-апреле 2023 года на графике связаны с двумя конкретными исправлениями: изменение обработки аттрибута autofocus в соответствии со спецификациями и динамическая настройка максимального размера «грязных» страниц в аллокаторе памяти mozjemalloc с увеличением этого размера для процессов с фоновым контентом.

В принципе, можно нажать на каждую точку на графике — и посмотреть, что изменилось с этим коммитом. Например, внезапные скачки в производительности Chrome связывают с изменениями в инфраструктуре тестирования.

Результаты Firefox и Chrome в разных тестах на всех платформах в более наглядном виде показаны здесь:

Как видим, Speedometer — не единственный бенчмарк, в котором Firefox удалось опередить конкурента. Хотя по многим другим тестам впереди Chrome.

Фреймворк Raptor запускается в среде Browsertime (Node.js, Selenium WebDriver) на Firefox Desktop, Firefox Android GeckoView, Fenix, Chromium и Chrome. Судя по списку программ, Mozilla выбрала в качестве ориентира именно Chrome. Поэтому мы не можем сравнить их с остальными браузерами в данной среде. Только друг с другом.

Raptor поддерживает три типа тестов:

  1. тесты на загрузку страниц;
  2. стандартные бенчмарки;
  3. «сценарные» тесты, например, измерение энергопотребления, процессора и памяти.

Список «стандартных бенчмарков» (пункт 2) состоит из стандартных независимых тестов, включая Speedometer 3 (sp3), MotionMark и JetStream. Тесты на загрузку страниц измеряют реальное время загрузки и рендеринга популярных сайтов, таких как YouTube и Википедия.

Список сайтов для измерения скорости загрузки страниц (десктопные тесты)

  • amazon
  • bing-search
  • buzzfeed
  • cnn
  • ebay
  • espn
  • expedia
  • facebook
  • fandom
  • google-docs
  • google-mail
  • google-search
  • google-slides
  • imdb
  • imgur
  • instagram
  • linkedin
  • microsoft
  • netflix
  • nytimes
  • office
  • outlook
  • paypal
  • pinterest
  • reddit
  • tumblr
  • twitch
  • twitter
  • wikia
  • wikipedia
  • yahoo-mail
  • youtube

Настройки одного из тестов:

  • alert on: fcp, loadtime, ContentfulSpeedIndex, PerceptualSpeedIndex, SpeedIndex, FirstVisualChange, LastVisualChange
  • alert threshold: 2.0
  • apps: firefox, chrome, chromium, safari, custom-car
  • browser cycles: 25
  • expected: pass
  • gecko profile entries: 14000000
  • gecko profile interval: 1
  • lower is better: true
  • page cycles: 25
  • page timeout: 60000
  • playback: mitmproxy
  • playback pageset manifest: mitm7-linux-firefox-youtube.manifest
  • playback version: 8.1.1
  • secondary url: https://www.youtube.com/watch?v=JrdEMERq8MA
  • test url: https://www.youtube.com
  • type: pageload
  • unit: ms
  • use live sites: false
  • Test Task:

В целом список тестов Raptor кажется максимально полным из того, что можно придумать для такой задачи. Это более объективная метрика, чем любой одиночный бенчмарк.

Примечание. В отдельных независимых тестах лучший результат по отдельным бенчмаркам могут показывать Edge, Safari или Opera. Так что звание «самого быстрого браузера» нельзя никому присудить однозначно, всё зависит от конкретного бенчмарка, версии браузера, включённых опций компиляции и флагов (настроек) браузера, а также платформы, на которой проводится тестирование (опции GPU-рендеринга, аппаратные функции CPU, настройки и версия ОС). Оптимальный вариант для пользователей — установить все интересующие браузеры на своём компьютере, запустить тесты на официальных сайтах (ссылки ниже) — и сравнить результаты в своей конкретной конфигурации. Вероятно, на macOS естественное преимущество получит Safari, а на Windows — Edge. Поскольку браузер и ОС в этих случаях разрабатывает одна компания (Apple и Microsoft, соответственно), она может применить некие общие системные оптимизации.

Chrome не сдаётся

Производительность можно измерять по-разному. В данный момент есть три основных бенчмарка для браузеров: Speedometer, MotionMark и JetStream.

В июне 2023 года разработчики Chrome заявили о достижении максимальных для себя результатов во всех трёх тестах. По их словам, чуть более чем за год результат Speedometer вырос с 300 (версия Chrome 101) до 491 (Chrome 116.0.5803.2 на M2 Macbook Air с включённым компилятором Maglev при сборке браузера).

Результат теста графической подсистемы MotionMark почти утроился с начала 2023 года до 4821,30 (Chrome M115.0.5773.4 на 13” M2 Macbook Pro).

Бенчмарк JetStream (JavaScript и WebAssembly, продвинутые веб-приложения) благодаря внедрению Maglev показал рост до 330,939 (Chrome 116.0.5803.2 на M2 Macbook Air с Maglev). Каков был прежний результат, не сообщается.

Обратим внимание, что тесты Google проводились на сборке Chrome с новым промежуточным JIT-компилятором Maglev, который «позволяет генерировать эффективный машинный код для всех релевантных функций в течение сотых долей секунды». По внутренним тестам, Maglev для движка V8 улучшил результат Jetstream на 7,5%, а Speedometer — на 5%.

На первый взгляд, результаты Google не очень сходятся с графиками Raptor, как будто они используют разные версии браузеров и бенчмарков (например, Speedometer 3 сильно отличается от Speedometer 2). Вопрос в том, какие тесты более соответствуют фактическому опыту пользователей.

Так или иначе, но соревнование разработчиков Firefox и Chrome на поле оптимизации можно только приветствовать.

Риск монополии

Некоторые специалисты считают, что нельзя допустить монополии Google Chrome на браузерном рынке на фоне того, часто всё больше сторонних браузеров переходят на движок и кодовую базу Chrome. В то же время аудитория Firefox продолжает снижаться. По статистике Mozilla, аудитория Firefox сократилась на 60 млн за четыре года, что составляет 24% аудитории (с пиковых 252 млн в 2019 году до 191 млн в июле 2023-го).

В такой ситуации появляются риски, что веб-сайты начнут разрабатывать в соответствии со стандартами, которые поддерживаются в Chrome, а не по официальным стандартам W3C. Недавняя история с удалением формата JPEG-XL из Chrome в октябре 2022 года стала хорошим индикатором нынешнего положения дел. Если бы не неожиданная поддержка со стороны Apple, этот качественный формат сжатия графики рисковал забвением. Однако на конференции WWDC23 компания Apple объявила о поддержке JPEG-XL во всех своих продуктах, включая Safari 17, новые версии iOS, iPadOS, macOS, watchOS и visionOS. Разработчики JPEG-XL с иронией восприняли тот факт, что первым браузером с поддержкой JPEG-XL стал Safari. Кто мог такое представить для формата, созданного при участии Google?

Монополия реально угрожает разработке новых форматов и перспективных технологий, которые могут оказаться на обочине истории по прихоти монополиста. Поэтому конкуренция со стороны Firefox очень важна для рынка браузеров, ведь Gecko по сути остался единственным независимым движком для рендеринга веб-страниц, не считая экспериментальных проектов Quantum и Servo от той же Mozilla.


ссылка на оригинал статьи https://habr.com/ru/articles/752862/

React Custom Hook: useScript

In this article series, we embark on a journey through the realm of custom React hooks, discovering their immense potential for elevating your development projects. Our focus today is on the «useScript» hook, one of the many carefully crafted hooks available in the collection of React custom hooks.

Github: https://github.com/sergeyleschev/react-custom-hooks

import useAsync from "../useAsync/useAsync"  export default function useScript(url) {     return useAsync(() => {         const script = document.createElement("script")         script.src = url         script.async = true         return new Promise((resolve, reject) => {             script.addEventListener("load", resolve)             script.addEventListener("error", reject)             document.body.appendChild(script)         })     }, [url]) }

One of the significant advantages of useScript is its ability to handle script loading asynchronously. By setting the script’s async attribute to true, you ensure that it won’t block the rendering of your application. This improves the performance and overall user experience, especially when dealing with larger scripts or slow network connections.

useScript can be used in various scenarios. For instance, you can load external libraries like jQuery, enabling you to harness its powerful functionalities without adding bulk to your bundle. Additionally, you can load analytics scripts, social media widgets, or any other script necessary for your application’s dynamic behavior.

import useScript from "./useScript"  export default function ScriptComponent() {     const { loading, error } = useScript(         "https://code.jquery.com/jquery-3.6.0.min.js"     )     if (loading) return <div>Loading</div>     if (error) return <div>Error</div>     return <div>{window.$(window).width()}</div> }

In the example above, we see how useScript is utilized in a ScriptComponent. The useScript hook is called with the URL of the jQuery library as an argument. The hook returns the loading and error states, which can be used to display a loading spinner or an error message accordingly. Once the script is successfully loaded, the component displays the current window width using jQuery.

Full Version | React Custom Hooks: https://habr.com/en/articles/746760/


ссылка на оригинал статьи https://habr.com/ru/articles/752822/

Мультиоблачная архитектура: проблемы и подводные камни

Одновременное использование нескольких облачных провайдеров в одной инфраструктуре — популярная модель, которую в перспективе рассматривают многие крупные компании. В этом посте мы рассмотрим сценарии перехода к мультиоблаку, возможные проблемы и некоторые ошибки, которые можно допустить, если вы всё-таки на это решились.

Что такое мультиоблако и какие пути к нему ведут 

Мультиоблако — это концепция использования услуг сразу нескольких облачных провайдеров для размещения сервисов. Компании прибегают к мультиоблаку, когда хотят добиться максимально подходящей для себя схемы получения услуг, избежать привязки к одному поставщику или создать задел на масштабирование инфраструктуры.

Развитие подобной инфраструктуры обычно начинается с одного облака. Компания выбирает облачного провайдера и переносит к нему необходимые приложения. Далее начинает присматриваться и к другим облачным провайдерам, планируя наиболее выгодные комбинации. AWS и Azure часто используют для контейнеризированных систем, GCP (облако Google) — для больших объемов данных и машинного обучения. Так постепенно формируется мультиоблако. Иногда поиск новых провайдеров связан с ограничениями местных регуляторов или жесткими требованиями к непрерывности бизнеса. Здесь появляется и такой вариант, как портативное облако — когда приложение является cloud-agnostic, то есть не имеет специфических требований и может быть развернуто на любой конфигурации облачных инфраструктур.

В конце концов, компании могут вырасти до архитектуры распределенного облака, где сочетаются и локальные ресурсы, и различные облачные инфраструктуры. Так работают крупные телеком-провайдеры и другие географически распределенные компании. Другая, вынужденная причина перехода к мультиоблачной модели — это покупка одной головной организацией нескольких новых компаний, у каждой из которых есть облачная инфраструктура, привязанная к своим провайдерам.

Проблемы мультиоблака по сравнению с выбором одного провайдера

Основные проблемы мультиоблачной инфраструктуры связаны с ее автоматизацией. Если вы используете AWS CloudFormation для облака Amazon и Google Deployment Manager для облака Google, то, вероятно, вам придется прописывать все свои политики отдельно для каждого провайдера — даже самые простые правила вроде допустимых конфигураций виртуальных машин. Здесь есть смысл прибегнуть к IaS-инструментам (Infrastructure as Code), таким как, например, Terraform.

Упоминая мультиоблако, люди нередко подразумевают именно создание портативных, cloud-agnostic приложений — эту концепцию мы упоминали несколько абзацев назад. Такой подход требует дополнительных затрат, поэтому стоит предварительно убедиться, действительно ли вам нужен cloud-agnostic подход и какие преимущества он даст именно в вашем случае. «Мы хотим двигаться в сторону cloud-agnostic, потому что для компании стратегически важно иметь поддержку различных облаков» — если это всё, к чему вы пришли, подумайте еще раз, конкретнее. Возможно, вы привязаны к жесткому SLA в пользовательском приложении, но при этом ориентируетесь на active-active или active-passive облачную инфраструктуру? Да, это один из случаев, когда cloud-agnostic может себя оправдать.

При этом cloud-agnostic подход предполагает, что вы сознательно оградите себя от всей функциональности, которая не является общей у возможных платформ. Все автоматизации, которые удобно организованы на той или иной платформе, придется отбросить — а это неизбежно приведет к дополнительным расходам. Если вы решите перевести на cloud-agnostic модель всю компанию — расходы вырастут еще больше. С другой стороны, вы можете выбрать единственную наиболее подходящую вам платформу и использовать ее по максимуму, со всеми фичами — это сэкономит ресурсы.

Для аналогии здесь можно привести две модели создания сложных программных комплексов, когда-то распространенные в индустрии — с использованием реляционных БД SQL или стандартизированной модели J2EE. Для первого решения существует общепринятый стандарт ANSI, на его возможности настолько слабы, что без проприетарных надстроек от вендоров эта модель бесполезна. Поэтому если вы выбираете конкретного вендора SQL, то становитесь привязаны к нему на уровне инфраструктуры. J2EE была разумной альтернативой такого вендор-лока до тех пор, пока в этой сфере не распространились решения на открытом коде.

Использование всеми облачными провайдерами какого-нибудь общего API было бы идеально — но не для самих провайдеров. Ведь они работают по подписной модели, живут на ваши регулярные платежи, а значит, не заинтересованы в том, чтобы вы могли взять и легко уйти к конкуренту. Нет, вас будут привлекать всеми возможными «уникальными фичами», чтобы вы как можно глубже увязали именно в одной экосистеме.

Очень важно систематизировать нагрузочные потоки приложений. Если размещать в облаке нечто реально критичное для бизнеса, то возникают определенные риски. Да, cloud agnostic — это выход: но будьте готовы к дополнительным расходам и отказу от вендорских «вишенок на торте».

Мировой рынок провайдеров облачной инфраструктуры в 1 квартале 2023 года (модели IaaS, Paas и частные облака)

Мировой рынок провайдеров облачной инфраструктуры в 1 квартале 2023 года (модели IaaS, Paas и частные облака)

Что стоит учитывать при переходе от одного облака к мультиоблаку

Начать, конечно же, стоит с формирования реальной цели на уровне бизнеса. Нужен четкий сценарий, какие проблемы бизнеса вы можете решить с помощью перехода на мультиоблако. Кроме того, переход на мультиоблако потребует от команды новых компетенций — учтите это. Подумайте о расходах: облака уже давно перестали быть сравнительно дешевыми, и добавление нового провайдера непременно увеличит бюджеты.

Далее при планировании автоматизации стоит по возможности придерживаться cloud-agnostic решений. Для деплоя и интеграции можно выбрать уже упомянутый Terraform, для защиты — Hashicorp, для раскатки политик — Open Policy Agent. Подойдите к этому более глобально, с учетом потенциальных потребностей и изменений в будущем.

Иногда о мультиоблаке задумываются для того, чтобы гарантировать работу бизнес-критичных приложений в разных регионах. Но прежде чем планировать такой переход, убедитесь: а ваш текущий, единственный облачный провайдер точно не способен обеспечить требуемую инфраструктуру во всех зонах доступности? Если вам необходим disaster recovery, то, может, будет логичней создать его в другой зоне доступности вашего текущего провайдера?

Если вы работаете в пределах одного провайдера, у вас есть один-единственный, отлаженный набор инструментов для разных целей. Но при подключении второго провайдера вы получаете другой аналогичный набор, и для каждого сценария появляется альтернатива. Да, есть перспектива собрать более удачный, комбинированный набор инструментов, но обязательно изучите, насколько совместимы между собой компоненты от разных провайдеров.

Другой важный вопрос — мониторинг. Если вам нужно будет сравнить данные. У каждого провайдера есть для этого свои инструменты, поэтому, если вы не можете поставить рядом несколько экранов при любой необходимости, подумайте о том, как объединить мониторинг в рамках одного инструмента — например, New Relic или Datadog.

Если обобщить и дополнить сказанное выше, можно выделить пять направлений для описания требований и оценки перехода на мультиоблако:

  • расходы на инфраструктуру;

  • идентификация и доступ;

  • реализация внутренних политик;

  • выделение и развертывание ресурсов;

  • мониторинг.

Антипаттерны работы в мультиоблачной модели

Напоследок выделим ряд опасных ситуаций, связанных с работой в мультиоблачной модели.

Не стоит планировать такой переход, если у вас отсутствуют универсальные метрики для деплоя приложений. Бывает, что один юнит в пределах организации использует AWS, другой начинает использовать GCP; без некоего общего знаменателя вы просто не оцените результат преобразований .

Второй антипаттерн связан с используемыми инструментами. Доступ к новым инструментам — это большой соблазн сконцентрировать внимание на них вместо того, чтобы попробовать выжать максимум из того, что есть. Так постепенно сформируется зоопарк решений — и целый сад подводных камней, связанных с их совместным использованием. Перед тем как расширять этот зоопарк, остановитесь и подумайте: а нельзя ли использовать уже имеющееся решения для этих задач?

Еще один вопрос связан с управлением — если, например, вы используете контейнеры в разных средах, то как вы организуете для них единые политики? Оцените возможные инструменты для этого — Rancher, Kublr, IBM Satellite, Google Anthos или что-нибудь еще.

Не стоит задумываться о мультиоблаке, если у вас в принципе не было опыта работы с облачными провайдерами. Некоторые начинают свой путь с того, что сразу выбирают пару провайдеров, у которых будет крутиться приложение. Выбрать Azure и GCP? Или AWS и Azure? Начинайте с чего-нибудь одного, а потом уже будет логично задуматься о совместимости. Иначе есть риск столкнуться с проблемами, которые съедят очень много времени — потому что вам придется разбираться как с работой каждого облака, так и с их совместимостью.

Выбор в пользу мультиоблака стоит тщательно продумать и оценить на разных уровнях. И чем меньше ваша компания, тем больше вероятность, что все вопросы разумнее решить в пределах одного провайдера. Текущего или альтернативного, но одного. А если уж вы решились на переход, то задумайтесь сразу и о том, как максимально унифицировать работу на всех уровнях в пределах всех провайдеров. В будущем это предотвратит немало проблем.


ссылка на оригинал статьи https://habr.com/ru/articles/752850/

React Custom Hook: useTimeout

In this article series, we embark on a journey through the realm of custom React hooks, discovering their immense potential for elevating your development projects. Our focus today is on the «useTimeout» hook, one of the many carefully crafted hooks available in the collection of React custom hooks.

Github: https://github.com/sergeyleschev/react-custom-hooks

import { useCallback, useEffect, useRef } from "react"  export default function useTimeout(callback, delay) {     const callbackRef = useRef(callback)     const timeoutRef = useRef()     useEffect(() => {         callbackRef.current = callback     }, [callback])     const set = useCallback(() => {         timeoutRef.current = setTimeout(() => callbackRef.current(), delay)     }, [delay])     const clear = useCallback(() => {         timeoutRef.current && clearTimeout(timeoutRef.current)     }, [])     useEffect(() => {         set()         return clear     }, [delay, set, clear])     const reset = useCallback(() => {         clear()         set()     }, [clear, set])     return { reset, clear } }

The «useTimeout» hook encapsulates the logic for setting, clearing, and resetting timeouts within a React component. It takes two parameters: a callback function and a delay duration in milliseconds. Whenever the specified delay elapses, the provided callback function is executed.

One of the significant advantages of this custom hook is that it ensures the callback function remains up to date even if it changes during component re-renders. By using a useRef to store the callback reference, the hook guarantees that the latest version of the function is always called.

Moreover, the «useTimeout» hook optimizes performance by utilizing useCallback to memoize the «set» and «clear» functions. This means that the functions are only recreated when their dependencies change, preventing unnecessary renders and enhancing efficiency.

import { useState } from "react" import useTimeout from "./useTimeout"  export default function TimeoutComponent() {     const [count, setCount] = useState(10)     const { clear, reset } = useTimeout(() => setCount(0), 1000)     return (         <div>             <div>{count}</div>             <button onClick={() => setCount(c => c + 1)}>Increment</button>             <button onClick={clear}>Clear Timeout</button>             <button onClick={reset}>Reset Timeout</button>         </div>     ) }

The «useTimeout» hook can be utilized in various scenarios where timed actions are required. For example, in a countdown component like the «TimeoutComponent» showcased above, you can easily implement a timer that resets after a specific duration. By using the «useTimeout» hook, you can effortlessly update the countdown value and manage the timeout without worrying about complex timeout management code.

Full Version | React Custom Hooks: https://habr.com/en/articles/746760/


ссылка на оригинал статьи https://habr.com/ru/articles/752832/